module.exports = permission => {
    const jwt = require('jsonwebtoken');
    const assert = require('http-assert');
    const User = require('../models/system/User')
    const Role = require('../models/system/Role')
    const Menu = require('../models/system/Menu')
    return async (req, res, next) => {
        // 获取前端传过来的请求头里的认证信息，处理后转为token，并验证token
        const token = String(req.headers.authorization || '').split(' ').pop();
        assert(token, 401, '系统检测到您还没有登录，请先登录！');
        // 服务端通过给出的secret验证生成的token，将之前传入的id解密出来，进行验证
        const { id } = jwt.verify(token, req.app.get('SECRET'));
        assert(id, 401, '系统检测到您还没有登录，请先登录！');
        // 根据id查找数据库，验证用户是否存在
        req.user = await User.findById(id);
        assert(req.user, 401, '系统检测到您还没有登录，请先登录！');
        /**
         *  判断该用户是否拥有操作权限
         *  '*:*:*'表示全部权限
         *  permission == '*:*:*'表示该请求不需要权限
         *  req.user.permissions.includes('*:*:*')用于验证该用户是否拥有全部权限
         *  req.user.permissions.includes(permission)用于验证当前用户是否具有permission权限
         * */
        if (req.user.userName === 'admin') {
            req.user.permissions = ['*:*:*']
        } else {
            const permissions = await Role.find({_id: {$in: req.user.roles}}).distinct('permissions')
            req.user.permissions = await Menu.find({_id: {$in: permissions}}).distinct('permission')
        }
        const hasPerm = permission === '*:*:*' || req.user.permissions.includes('*:*:*') || req.user.permissions.includes(permission)
        assert(hasPerm, 401, '没有相关操作权限，请联系管理员。')
        await next();
    }
}
